package com.im.activity;

import java.util.ArrayList;
import java.util.List;

import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.packet.Presence;

import roboguice.inject.InjectView;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import com.core.sdk.core.BaseEvent;
import com.core.sdk.core.LogUtil;
import com.core.sdk.core.UITask;
import com.core.sdk.ui.listview.PullToRefreshListView;
import com.core.sdk.ui.listview.PullToRefreshListView.OnRefreshListener;
import com.core.sdk.utils.GsonUtil;
import com.core.sdk.utils.IOUtil;
import com.core.sdk.utils.ImageUtil;
import com.core.sdk.utils.IntentUtil;
import com.im.R;
import com.im.adapter.MoreChatAdapter;
import com.im.adapter.SmackMessageAdapter;
import com.im.app.ImApplication;
import com.im.audio.PlayerManager;
import com.im.audio.RecorderManager;
import com.im.db.DBManagerService;
import com.im.db.event.XmppMessageRequestEvent;
import com.im.db.event.XmppMessageRequestEvent.Operate;
import com.im.db.event.XmppMessageResponseEvent;
import com.im.event.FileResultReivedEvent;
import com.im.event.FileResultSendEvent;
import com.im.event.FileSendEvent;
import com.im.event.FileType;
import com.im.event.MessageResultReceivedEvent;
import com.im.event.MessageResultSendEvent;
import com.im.event.MessageSendEvent;
import com.im.model.MoreChat;
import com.im.model.XmppMessage;
import com.im.service.SmackService;

public class SessionActivity extends MyBaseActivity implements OnClickListener, TextWatcher, OnTouchListener, OnItemClickListener,OnRefreshListener {

	@InjectView(R.id.act_session_lv)
	PullToRefreshListView lv;

	/** 发送文本消息的按钮 */
	@InjectView(R.id.act_session_send_text)
	Button btnSendText;

	/** 切换按钮 控制(文本输入框 - 语音录入按钮)是否显示 */
	@InjectView(R.id.act_session_send_btn)
	ImageButton btnSwitch;

	@InjectView(R.id.act_session_msg_text)
	EditText msgText;

	@InjectView(R.id.act_session_msg_voice)
	Button msgVoice;

	@InjectView(R.id.act_session_title)
	TextView topTitle;

	@InjectView(R.id.act_session_user_status)
	TextView userStatus;

	@InjectView(R.id.act_session_add)
	ImageView ivAdd;

	@InjectView(R.id.act_session_gridview)
	GridView mGridView;

	protected InputMethodManager mInputMethodManager = null;
	SmackMessageAdapter adapter = null;
	RosterEntry rosterEntry = null;
	String myJID = null;

	MoreChatAdapter mChatAdapter = null;

	/** 音频播放 */
	PlayerManager pm = new PlayerManager();

	public static Intent createIntent(Context cxt, RosterEntry rosterEntry) {
		Intent it = new Intent(cxt, SessionActivity.class);
		Bundle bd = new Bundle();
		String json = GsonUtil.getGson().toJson(rosterEntry);
		bd.putString("data", json);
		it.putExtras(bd);
		return it;
	}

	private final long PAGE_NO = 0;
	private final long PAGE_SIZE = 5;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		mInputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
		String json = getIntent().getExtras().getString("data");
		rosterEntry = GsonUtil.getGson().fromJson(json, RosterEntry.class);
		btnSendText.setOnClickListener(this);
		btnSwitch.setOnClickListener(this);
		msgText.addTextChangedListener(this);
		msgVoice.setOnTouchListener(this);
		ivAdd.setOnClickListener(this);

		myJID = getUserJID();
		adapter = new SmackMessageAdapter(this, myJID);
		lv.setAdapter(adapter);
		lv.setOnItemClickListener(this);
		lv.setOnRefreshListener(this);

		String status = null;
		Presence pre = ((ImApplication) getApplicationContext()).getRoster().getPresence(rosterEntry.getUser());
		if (pre == null || pre.getType().ordinal() != Presence.Type.available.ordinal()) {
			status = "离线";
		} else {
			status = "在线";
		}
		userStatus.setText(status);
		String tt = rosterEntry.getName() != null ? rosterEntry.getName() : rosterEntry.getUser();
		topTitle.setText(tt);

		mChatAdapter = new MoreChatAdapter(this);
		mGridView.setAdapter(mChatAdapter);
		mGridView.setOnItemClickListener(this);
		initMoreChatAdapter();
		requestLoadHistoryRecord(PAGE_NO,PAGE_SIZE,System.currentTimeMillis());
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		adapter.destory();
		pm.destory();
		requestMarkToReaded();
		receivedMessageIdList.clear();
		receivedMessageIdList =null;
	}

	@Override
	public void onTopRefresh() {
		XmppMessage xm = adapter.getItem(0).getData();
		long time = xm.getCreateTime();
		requestLoadHistoryRecord(PAGE_NO, PAGE_SIZE,time);
	}

	@Override
	public boolean onBottomRefresh() {
		return false;
	}

	@Override
	public void onClick(View v) {
		if (v == btnSendText) {
			String text = msgText.getText().toString();
			String userJID = rosterEntry.getUser();
			MessageSendEvent evt = new MessageSendEvent(findLocation(SmackService.class), userJID, text);
			sendEvent(evt);
		} else if (v == btnSwitch) {
			boolean selected = btnSwitch.isSelected();
			btnSwitch.setSelected(!selected);
			if (btnSwitch.isSelected()) { // 语音消息
				msgText.setVisibility(View.GONE);
				msgVoice.setVisibility(View.VISIBLE);
				closeInputMethod(msgText);
			} else { // 文字消息
				msgText.setVisibility(View.VISIBLE);
				msgVoice.setVisibility(View.GONE);
			}
		} else if (v == ivAdd) {
			int visable = mGridView.getVisibility();
			if (visable == View.VISIBLE) {
				mGridView.setVisibility(View.GONE);
			} else {
				mGridView.setVisibility(View.VISIBLE);
			}
			// mGridView.setFocusable(true);
			// mGridView.setFocusableInTouchMode(true);
			// mGridView.requestFocus();
		}
	}

	RecorderManager mRecorder = null;

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		final int action = event.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			LogUtil.d(tag, "松开发送,ACTION_DOWN");
			msgVoice.setText("松开发送");
			msgVoice.setTextColor(this.getResources().getColor(R.color.white));

			mRecorder = new RecorderManager();
			mRecorder.start();
			break;
		case MotionEvent.ACTION_UP:
			LogUtil.d(tag, "按住说话,Action_UP");
			msgVoice.setText("按住说话");
			msgVoice.setTextColor(this.getResources().getColor(R.color.bg_solid_blue));
			mRecorder.shutdown();
			sendFile(mRecorder.getSavePath(), FileType.audio, mRecorder.getRecorderTime());
			break;
		case MotionEvent.ACTION_MOVE:
			break;
		default:
			break;
		}
		return false;
	}

	/** 通过是否输入文本来确定显示(切换按钮还是文本发送按钮) */
	@Override
	public void afterTextChanged(Editable et) {
		if (et.toString().length() > 0) {
			btnSwitch.setVisibility(View.GONE);
			btnSendText.setVisibility(View.VISIBLE);
		} else {
			btnSwitch.setVisibility(View.VISIBLE);
			btnSendText.setVisibility(View.GONE);
		}
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count, int after) {

	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {

	}

	private List<String> receivedMessageIdList = new ArrayList<String>();
	@Override
	public void executeEvent(BaseEvent evt) {
		super.executeEvent(evt);
		if(evt instanceof XmppMessageResponseEvent){
			XmppMessageResponseEvent event = (XmppMessageResponseEvent)evt;
			List<XmppMessage> list = event.getResult();
			if(event.getOp() == Operate.unread && list != null && list.size() > 0){
				for (XmppMessage xm : list) {
					addIdToReceivedMessageList(xm.getId());
				}
			}
			procressXmppMessageResponseEvent(event);
			return ;	
		}
		XmppMessage sm = null;
		if (evt instanceof MessageResultReceivedEvent) {
			sm = ((MessageResultReceivedEvent) evt).getXmppMessage();
			addIdToReceivedMessageList(sm.getId());
		} else if (evt instanceof MessageResultSendEvent) {
			sm = ((MessageResultSendEvent) evt).getXmppMessage();
		} else if (evt instanceof FileResultReivedEvent) {
			FileResultReivedEvent fre = (FileResultReivedEvent) evt;
			sm = fre.getXmppMessage();
			addIdToReceivedMessageList(sm.getId());
		} else if (evt instanceof FileResultSendEvent) {
			FileResultSendEvent fre = (FileResultSendEvent) evt;
			sm = fre.getXmppMessage();
		}
		if (sm != null){
			postRunOnUi(new UITask(this, sm) {
				@Override
				public void run() {
					procressXmppMessage((XmppMessage) getData());
				}
			});
		}
	
	}
	
	private void addIdToReceivedMessageList(int id){
		if(id > 0){
			receivedMessageIdList.add(String.valueOf(id));
		}
	}

	private void procressXmppMessage(XmppMessage sm) {
		if (sm.getMsgType() == XmppMessage.MSG_TYPE_TEXT) {
			if (sm.getFromUser().startsWith(myJID)) {
				msgText.setText("");
			}
		}
		adapter.addItem(sm, null);
		adapter.notifyDataSetChanged();
		
		//默认选到最后一页
		int position = adapter.getCount() - lv.getHeaderViewsCount();
		lv.setSelection(position);
	}
	
	/** 是否加载过未读消息 */
	boolean loadUnReadMsg = false;
	private void procressXmppMessageResponseEvent(XmppMessageResponseEvent resposneEvent){
		postRunOnUi(new UITask(this,resposneEvent) {
			@Override
			public void run() {
				XmppMessageResponseEvent respEvt = (XmppMessageResponseEvent)this.getData();
				Operate op = respEvt.getOp();
				if(op == Operate.loadHistory){
					lv.setTopRefreshComplete();
					List<XmppMessage> list = respEvt.getResult();
					if(list != null && list.size() > 0){
						addMessageByHistory(list);
					}
					if(!loadUnReadMsg){
						loadUnReadMsg=true;
						requestUnReadMsg();
					}
				}else if(op == Operate.markToReaded){
					
				}else if(op == Operate.unread){
					List<XmppMessage> list = respEvt.getResult();
					if(list != null && list.size() > 0){
						addMessageByUnRead(list);
					}
				}
			}
		});
	}

	/** 添加历史消息 */
	private void addMessageByHistory(List<XmppMessage> list) {
		if (list == null || list.size() ==0)
			return;
		List<Void> stateList = new ArrayList<Void>();
		for (int i = 0; i < list.size(); i++) {
			stateList.add(null);
		}
		adapter.addItems(0, list, stateList);
		lv.setSelection(list.size()-1);
		adapter.notifyDataSetChanged();
	}
	
	/** 添加未读消息 */
	private void addMessageByUnRead(List<XmppMessage> list){
		if (list == null || list.size() ==0)
			return;
		int size = adapter.getCount();
		for (XmppMessage xm : list) {
			adapter.addItem(xm, null);
		}
		lv.setSelection(size);
		adapter.notifyDataSetChanged();
	}
	

	@Override
	protected int getContentView() {
		return R.layout.act_session;
	}

	private void initMoreChatAdapter() {
		mChatAdapter.addItem(new MoreChat(R.drawable.chat_tool_camera), null);
		mChatAdapter.addItem(new MoreChat(R.drawable.chat_tool_photo), null);
		mChatAdapter.addItem(new MoreChat(R.drawable.chat_tool_send_file), null);
		mChatAdapter.addItem(new MoreChat(R.drawable.chat_tool_location), null);
		mChatAdapter.notifyDataSetChanged();
	}
	
	/** 获得历史记录 */
	private void requestLoadHistoryRecord(long pageNo,long pageSize,long time){
		XmppMessageRequestEvent.ParamEntity param = new XmppMessageRequestEvent.ParamEntity();
		param.setOtherUser(rosterEntry.getUser());
		param.setPageNo(pageNo);
		param.setPageSize(pageSize);
		param.setTime(time);
		XmppMessageRequestEvent xme = new XmppMessageRequestEvent(findLocation(DBManagerService.class), Operate.loadHistory, param);
		sendEvent(xme);
	}
	
	/** 获得离线+未读消息 */
	private void requestUnReadMsg(){
		XmppMessageRequestEvent.ParamEntity param = new XmppMessageRequestEvent.ParamEntity();
		param.setOtherUser(rosterEntry.getUser());
		XmppMessageRequestEvent xme = new XmppMessageRequestEvent(findLocation(DBManagerService.class), Operate.unread, param);
		sendEvent(xme);
	}
	
	/** 将所有已收到的消息标记灵已读 */
	private void requestMarkToReaded(){
		XmppMessageRequestEvent.ParamEntity param = new XmppMessageRequestEvent.ParamEntity();
		param.setIds(new ArrayList<String>(receivedMessageIdList));
		XmppMessageRequestEvent xme = new XmppMessageRequestEvent(findLocation(DBManagerService.class), Operate.markToReaded, param);
		sendEvent(xme);
	}

	/** 关闭输入法 */
	protected void closeInputMethod(EditText et) {
		try {
			if (mInputMethodManager != null && mInputMethodManager.isActive()) {
				mInputMethodManager.hideSoftInputFromWindow(et.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/** 发送文件 */
	private void sendFile(String filePath, FileType fileType, String description) {
		try {
			String jid = rosterEntry.getUser() + "/Spark 2.6.3";
			FileSendEvent evt = new FileSendEvent(findLocation(SmackService.class), fileType, filePath, jid);
			if (description != null && description.trim().length() > 0) {
				evt.setDescription(description);
			}
			sendEvent(evt);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private final int CODE_REQUEST_CAMERA = 1;
	private final int CODE_REQUEST_PICTURE_PICK = 2;
	private final int CODE_REQUEST_CROP = 100;
	String sourceOutPutUri = null;
	String cropOutPutUri = null;

	@Override
	public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
		if (parent == mGridView) {
			if (position == 0) {
				sourceOutPutUri = IOUtil.getExternalStoragePath() + "tmp_source.jpg";
				Intent it = IntentUtil.createPhotoTakeIntent(sourceOutPutUri);
				startActivityForResult(it, CODE_REQUEST_CAMERA);
			} else if (position == 1) {
				startActivityForResult(IntentUtil.createPhotoPickerIntent(), CODE_REQUEST_PICTURE_PICK);
			}
		} else if (parent == lv) {
			int pos = position - lv.getHeaderViewsCount();
			XmppMessage sm = adapter.getItem(pos).getData();
			if (sm == null)
				return;
			if (sm.getMsgType() != XmppMessage.MSG_TYPE_AUDIO)
				return;
			String amrFilePath = sm.getMsgContent();
			if (amrFilePath != null) {
				pm.play(amrFilePath);
			}
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode != Activity.RESULT_OK)
			return;
		if (requestCode == CODE_REQUEST_CAMERA) {
			cropOutPutUri = IOUtil.getExternalStoragePath() + "tmp_crop.jpg";
			Intent it = IntentUtil.createPhotoCropIntent(sourceOutPutUri, cropOutPutUri, 400, 400);
			startActivityForResult(it, CODE_REQUEST_CROP);
		} else if (requestCode == CODE_REQUEST_CROP) {
			sendFile(cropOutPutUri, FileType.img, "sendTime:"+System.currentTimeMillis());
		} else if (requestCode == CODE_REQUEST_PICTURE_PICK) {
			Uri uri = data.getData();
			String fileLocalePath = ImageUtil.getLocalPathFromUri(uri, this);
			cropOutPutUri = IOUtil.getExternalStoragePath() + "tmp_crop.jpg";
			Intent it = IntentUtil.createPhotoCropIntent(fileLocalePath, cropOutPutUri, 400, 400);
			startActivityForResult(it, CODE_REQUEST_CROP);
		}
	}
	
	
}
